﻿using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Controls;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.SystemUI;
using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace ComponentGIS.Tool
{
    class CreateFeatureTool : ICommand, ITool
    {
        #region 字段属性
        public static IFeatureLayer FeatureLayer { get; set; }
        private Stack<IPoint> m_pPntStack;
        private Stack<IPoint> m_pPntStackCopy;
        private IHookHelper m_pHookHelper;
        private IEngineEditor m_pEditor;
        private IEngineEditSketch m_pSketch;
        public IEngineEditSketch EditSketch
        {
            get { return m_pSketch; }
        }
        private bool canUndo = false;
        public bool CanUndo
        {
            get { return canUndo; }
        }
        private bool canRedo = false;
        public bool CanRedo
        {
            get { return canRedo; }
        }
        private bool isFinishedSketch = false;
        public bool IsFinishedSketch
        {
            get { return isFinishedSketch; }
        }

        #endregion

        #region 构造函数
        public CreateFeatureTool()
        {
            m_pPntStack = new Stack<IPoint>();
            m_pPntStackCopy = new Stack<IPoint>();
            m_pEditor = new EngineEditorClass();
            m_pSketch = (IEngineEditSketch)m_pEditor;
        }
        #endregion

        #region ITool成员
        public int Cursor
        {
            get
            {
                ISystemMouseCursor pMouse = new SystemMouseCursorClass();
                pMouse.Load(esriSystemMouseCursor.esriSystemMouseCursorCrosshair);
                return pMouse.Cursor;
            }
        }

        public bool Deactivate()
        {
            return true;
        }

        public bool OnContextMenu(int x, int y)
        {
            return false;
        }

        public void OnDblClick()
        {
            m_pSketch.FinishSketch();
            isFinishedSketch = true;
        }

        public void OnKeyDown(int keyCode, int shift)
        {
        }

        public void OnKeyUp(int keyCode, int shift)
        {
        }

        public void OnMouseDown(int button, int shift, int x, int y)
        {
            //转成地图坐标
            IPoint point = m_pHookHelper.ActiveView.ScreenDisplay.DisplayTransformation.ToMapPoint(x, y);
            if (button == 1)
            {
                m_pSketch.AddPoint(point, true);//添加点
                m_pPntStack.Clear();//清空栈
                m_pPntStackCopy.Clear();//清空备份栈
                canUndo = true;//允许撤销
                isFinishedSketch = false;//创建要素过程中
            }
        }

        public void OnMouseMove(int button, int shift, int x, int y)
        {
        }

        public void OnMouseUp(int button, int shift, int x, int y)
        {

        }

        public void Refresh(int hdc)
        {
        }
        #endregion

        #region ICommand成员
        public int Bitmap
        {
            get { return -1; }
        }

        public string Caption
        {
            get { return "创建要素"; }
        }

        public string Category
        {
            get { return "空间编辑"; }
        }

        public bool Checked
        {
            get { return false; }
        }

        public bool Enabled
        {
            get { return true; }
        }

        public int HelpContextID
        {
            get { return -1; }
        }

        public string HelpFile
        {
            get { return string.Empty; }
        }

        public string Message
        {
            get { return "创建要素"; }
        }

        public string Name
        {
            get { return "CreateFeatureTool"; }
        }

        public void OnClick()
        {

        }

        public void OnCreate(object Hook)
        {
            m_pHookHelper = new HookHelperClass();
            m_pHookHelper.Hook = Hook;
        }

        public string Tooltip
        {
            get { return "创建要素"; }
        }
        #endregion

        #region 方法成员
        public void Undo()
        {
            try
            {
                //1 初检
                if (!m_pSketch.Geometry.IsEmpty)
                {
                    //2 入栈
                    m_pPntStack.Push(m_pSketch.LastPoint);
                    m_pPntStackCopy = m_pPntStack;//备份
                    //3 删除
                    IPointCollection pPntCol = (IPointCollection)m_pSketch.Geometry;
                    if (m_pSketch.GeometryType == esriGeometryType.esriGeometryPolygon
                        && pPntCol.PointCount > 1)
                        pPntCol.RemovePoints(pPntCol.PointCount - 2, 1);
                    else
                        pPntCol.RemovePoints(pPntCol.PointCount - 1, 1);
                    m_pSketch.Geometry = (IGeometry)pPntCol;
                    //4 复检/更新许可
                    if (m_pSketch.Geometry.IsEmpty)
                        canUndo = false;
                    canRedo = true;
                }
                //5 刷新
                m_pHookHelper.ActiveView.Refresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void Redo()
        {
            try
            {
                //1 初检
                if (m_pPntStack.Count > 0)
                {
                    //2 出栈
                    IPoint pPnt = m_pPntStack.Pop();
                    //3 复检
                    if (m_pPntStack.Count == 0)
                    {
                        m_pPntStack = m_pPntStackCopy;
                        canRedo = false;
                    }
                    //4 添加
                    m_pSketch.AddPoint(pPnt, true);
                    //5 许可
                    canUndo = true;
                }
                //6 刷新
                m_pHookHelper.ActiveView.Refresh();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        public void ChangeTargetLyr()
        {
            IEngineEditLayers pEditLyrs = (IEngineEditLayers)m_pSketch;
            pEditLyrs.SetTargetLayer(FeatureLayer, 0);
        }
        #endregion
    }
}
